package com.itheima.health.h5.controller;

import com.github.wxpay.sdk.WXPayUtil;
import com.itheima.health.entity.Result;
import com.itheima.health.pojo.Order;
import com.itheima.health.pojo.Setmeal;
import com.itheima.health.service.OrderService;
import com.itheima.health.service.SetmealService;
import com.itheima.health.utils.aliyunoss.AliyunUtils;
import com.itheima.health.utils.payUtils.MyWXPayUtil;
import com.itheima.health.utils.payUtils.PayUtils;
import com.itheima.health.utils.resources.MessageConstant;
import com.itheima.health.utils.resources.RedisMessageConstant;
import com.itheima.health.utils.sms.SmsUtils;
import com.itheima.health.utils.sms.ValidateCodeUtils;
import com.itheima.health.vo.SetmealVO;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
public class OrderController {

    @Reference
    private OrderService orderService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("order/sendCodeToPhone/{telephone}")
    public  Result  sendCodeToPhone(@PathVariable("telephone") String telephone){
        try{
           //  生成一个验证码  发送给客户手机
            String code = ValidateCodeUtils.generateValidateCode(4);
            System.out.println("校验的验证码："+code);
//            封装用户手机号和验证码
             //   消息 投递  mq
            SmsUtils.validUserTelephone(telephone,code);
            Map  map = new HashMap();
            map.put("telephone",telephone);
            map.put("code",code);


            //rabbitTemplate.convertAndSend("heima-queue",map);
            redisTemplate.opsForValue().set(RedisMessageConstant.SENDTYPE_ORDER+telephone,code,90, TimeUnit.SECONDS);
            return new Result(true, MessageConstant.SEND_VALIDATECODE_SUCCESS);
        }catch (Exception e){
            return new Result(false, MessageConstant.SEND_VALIDATECODE_FAIL);
        }
    }

    @GetMapping("order/findOrderDetailByOrderId/{id}")
    public  Result  findOrderDetailByOrderId(@PathVariable("id") int id){
        try{
              Map map = orderService.findOrderDetailByOrderId(id);
            return new Result(true, MessageConstant.QUERY_ORDER_DETAIL_SUCCESS,map);
        }catch (Exception e){
            return new Result(false, MessageConstant.QUERY_ORDER_DETAIL_FAIL);
        }
    }


    @PostMapping("order/add")
    public  Result  add(@RequestBody Map map){
        try{
            //  1. 判断表单提交的验证码和redis保存的验证码是否一致
            String codeForm  = (String)map.get("validateCode");
            String telephone  = (String)map.get("telephone");
            String redisCode = (String) redisTemplate.opsForValue().get(RedisMessageConstant.SENDTYPE_ORDER+telephone);
            if(redisCode==null){
                return new Result(false, "验证码过期！");
            }else{
                //  比对验证码
                if(redisCode.equals(codeForm)){
                      // 验证码正确
                    Order order =  orderService.add(map); //  预约失败 。。。add方法 抛出异常 给出指定信息

                    //订单id
                    Integer id = order.getId();

                    String uuid = UUID.randomUUID().toString();
                    System.out.println(uuid);
                    MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
                        @Override
                        public Message postProcessMessage(Message message) throws AmqpException {
                            //消息持久化
                            message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                            //设置延迟时间
                            message.getMessageProperties().setDelay(10000);
                            return message;
                        }
                    };
                    System.out.println("消息发送时间:" + System.currentTimeMillis());
                    //rabbitTemplate.convertAndSend("delay-exchange","delay",id,messagePostProcessor,new CorrelationData(uuid));
                    return new Result(true, MessageConstant.ADD_ORDER_SUCCESS,order);
                }else{
                    //  验证码输入错误
                    return new Result(false, "验证码输入错误");
                }
            }
        }catch (Exception e){
            return new Result(false, e.getMessage());
        }
    }

    //生成二维码需要的URL
    @GetMapping("order/findOrderDetailByOrderId2/{id}")
    public Result findOrderDetailByOrderId2(@PathVariable("id") int id) {
        try {
            //Map map = orderService.findOrderDetailByOrderId(id);
            Map map = new HashMap();
            String url = PayUtils.createOrder(id + "", 1);
            map.put("url", url);
            System.out.println(url);
            return new Result(true, MessageConstant.QUERY_ORDER_DETAIL_SUCCESS, map);
        } catch (Exception e) {
            return new Result(false, MessageConstant.QUERY_ORDER_DETAIL_FAIL);
        }
    }

    @GetMapping("order/queryStatus/{id}")
    public Result queryStatus(@PathVariable("id") int id) {
        try {
            Boolean flag = orderService.queryStatus(id);
            if (flag) {
                return new Result(true, "已支付");
            } else {

                return new Result(false, "未支付");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.QUERY_ORDER_DETAIL_FAIL);
        }
    }

    @RequestMapping("callback")
    public void orderCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
        InputStream inputStream = request.getInputStream();
        // PayConfig payConfig = new PayConfig();
        PayUtils payUtils = new PayUtils();
        //BufferedReader是包装设计模式，性能更搞
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        StringBuffer sb = new StringBuffer();
        //1、将微信回调信息转为字符串
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
        in.close();
        inputStream.close();
        //2、将xml格式字符串格式转为map集合
        Map<String, String> callbackMap = WXPayUtil.xmlToMap(sb.toString());
        System.out.println(callbackMap.toString());
        //3、转为有序的map
        SortedMap<String, String> sortedMap = MyWXPayUtil.getSortedMap(callbackMap);
        //4、判断签名是否正确
        //   if(MyWXPayUtil.isCorrectSign(sortedMap,"T6m9iK73b0kn9g5v426MKfHQH7X8rKwb")){
        //5、判断回调信息是否成功
        if ("SUCCESS".equals(sortedMap.get("result_code"))) {
            //获取商户订单号
            //商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|* 且在同一个商户号下唯一
            String orderNo = sortedMap.get("out_trade_no");
            System.out.println(orderNo);
            //6、数据库查找订单,如果存在则根据订单号更新该订单
            //  Order dbOrder = orderService.findByOrderNo(orderNo);
            //   System.out.println(dbOrder);
            // if(dbOrder != null && dbOrder.getState()==0){  //判断逻辑看业务场景
            //    Order Order = new Order();
            //   Order.setOpenid(sortedMap.get("openid"));
            //    Order.setOutTradeNo(outTradeNo);
            //    Order.setNotifyTime(new Date());
            //修改支付状态，之前生成的订单支付状态是未支付，这里表面已经支付成功的订单
            //    Order.setState(1);
            //根据商户订单号更新订单
            int rows = orderService.updateOrderStatus(orderNo);
            System.out.println(rows);
            //7、通知微信订单处理成功
            if (rows > 0) {
                Map<String, String> map = new HashMap<>();
                map.put("return_code", "SUCCESS");
                map.put("return_msg", "OK");
                String return_msg = WXPayUtil.mapToXml(map);
                System.out.println("return_msg = " + return_msg);
//response.setContentType("text/xml");
                response.getWriter().write(return_msg);
                //   response.sendRedirect();
                return;
            }
        }
        //       }
        //7、通知微信订单处理失败

        response.setContentType("text/xml");
        response.getWriter().println("fail");


    }



    //@PostMapping("abc")
    /*public void show(HttpServletRequest request, HttpServletResponse response) {
//        PageData pd=this.getPageData();
        InputStream inputStream =  request.getInputStream();
        //BufferedReader是包装设计模式，性能更搞
        BufferedReader in =  new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
        StringBuffer sb = new StringBuffer();
        //1、将微信回调信息转为字符串
        String line ;
        while ((line = in.readLine()) != null){
            sb.append(line);
        }
        in.close();
        inputStream.close();
        //2、将xml格式字符串格式转为map集合
        Map<String,String> callbackMap = WXPayUtil.xmlToMap(sb.toString());
        System.out.println(callbackMap.toString());
        //3、转为有序的map
        SortedMap<String,String> sortedMap = WXPayUtil.getSortedMap(callbackMap);
        //4、判断签名是否正确
        if(WXPayUtil.isCorrectSign(sortedMap,weChatConfig.getKey())){
            //5、判断回调信息是否成功
            if("SUCCESS".equals(sortedMap.get("result_code"))){
                //获取商户订单号
                //商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|* 且在同一个商户号下唯一
                String outTradeNo = sortedMap.get("out_trade_no");
                System.out.println(outTradeNo);
                //6、数据库查找订单,如果存在则根据订单号更新该订单
                VideoOrder dbVideoOrder = videoOrderService.findByOutTradeNo(outTradeNo);
                System.out.println(dbVideoOrder);
                if(dbVideoOrder != null && dbVideoOrder.getState()==0){  //判断逻辑看业务场景
                    VideoOrder videoOrder = new VideoOrder();
                    videoOrder.setOpenid(sortedMap.get("openid"));
                    videoOrder.setOutTradeNo(outTradeNo);
                    videoOrder.setNotifyTime(new Date());
                    //修改支付状态，之前生成的订单支付状态是未支付，这里表面已经支付成功的订单
                    videoOrder.setState(1);
                    //根据商户订单号更新订单
                    int rows = videoOrderService.updateVideoOderByOutTradeNo(videoOrder);
                    System.out.println(rows);
                    //7、通知微信订单处理成功
                    if(rows == 0){
                        response.setContentType("text/xml");
                        response.getWriter().println("success");
                        return;
                    }
                }}
        }
        //7、通知微信订单处理失败
        response.setContentType("text/xml");
        response.getWriter().println("fail");
        System.out.println("hello");
    }*/
}
